/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       adv_artifact.cpp

	$Header: /game/adv_artifact.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_artifact.h"

#include "adv_object_model.h"
#include "adventure_ai.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_map_window.h"
#include "adventure_sounds.h"
#include "ai_value.h"
#include "army.h"
#include "artifact_type.h"
#include "artifact_properties.h"
#include "basic_dialog.h"
#include "bitmap_layer_cache_window.h"
#include "button.h"
#include "button_cache.h"
#include "default_artifact_properties.h"
#include "default_artifacts.h"
#include "elements_of.h"
#include "mouse_event.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "simple_dialog.h"
#include "string_pair.h"

static int const k_spell_artifact_map_version  = 1;

// -------------------------------------------------------
// set artifact keywords
// -------------------------------------------------------
static void set_model_names( std::string*			model_name, 
							 char const*			folder,
							 t_char_ptr_pair const* keywords,
							 int					size )
{
	std::string name;

	while (size--)
	{
		name = folder;
		name += keywords[size].keyword;
		model_name[keywords[size].value] = name;
	}
}

// -------------------------------------------------------
// get a stationary adventure object model, given an artifact type
// -------------------------------------------------------
static std::string get_artifact_model_name( t_artifact_type type )
{
	static bool			initialized = false;
	static std::string  model_names[k_artifact_type_count];

	if (!initialized)
	{
		static t_char_ptr_pair const k_amulets[] =
		{
			// amulets
			{ k_artifact_amulet_of_fear,			"amulet of fear" },
			{ k_artifact_amulet_of_the_undertaker,	"amulet of the undertaker" },
			{ k_artifact_ankh_of_life,				"anhk of life" },
			{ k_artifact_fizbin_of_misfortune,		"collar of misfortune" },
			{ k_artifact_druids_chain,				"Druids chain" },
			{ k_artifact_medal_of_honor,			"medal of honor" },
			{ k_artifact_mirror_of_spell_turning,	"mirror revenge" },
			{ k_artifact_necklace_of_charm,			"neckless of charm" },
			{ k_artifact_staads_scarab_of_summoning,	"scarab summoning" },
			{ k_artifact_statesmans_medal,				"statesmans medal" },
		};
		static t_char_ptr_pair const k_armors[] = 
		{
			{ k_artifact_adamantine_armor,				"adamantine armor" },
			{ k_artifact_armor_of_chaos,				"armor of chaos" },
			{ k_artifact_armor_of_darkness,				"armor of death" },
			{ k_artifact_armor_of_light,				"armor of light" },
			{ k_artifact_armor_of_order,				"armor of order" },
			{ k_artifact_breastplate_of_regeneration,	"breastplate of regeneration" },
			{ k_artifact_brimstone_breastplate,			"brimstone breastplate" },
			{ k_artifact_chainmail,						"chain mail" },
			{ k_artifact_dragon_scale_armor,			"dragonscale armor" },
			{ k_artifact_elven_chainmail,				"elven chainmail" },
			{ k_artifact_golden_plate_mail,				"golden platemail" },
			{ k_artifact_gryphonhearts_plate_mail,		"gryphonhearts platemail" },
			{ k_artifact_leather_armor,					"leather" },
			{ k_artifact_plate_mail,					"plate mail" },
			{ k_artifact_scale_mail_of_strength,		"scalemail of strength" },
			{ k_artifact_unnatural_armor,				"unnatural armor" },
		};
		static t_char_ptr_pair const k_boots[] = 
		{
			k_artifact_boots_of_levitation,				"boots of levitation",
			k_artifact_surefooted_boots,				"boots of the explorer",
			k_artifact_boots_of_speed,					"boots of travel",
			k_artifact_swamp_boots,						"crocodile",
			k_artifact_fireproof_boots,					"FireProofBoots",
			k_artifact_sandwalker_sandals,				"Sandwalker Sandals",
			k_artifact_snowshoes,						"Snow Shoes",
			k_artifact_ogs_sandals,						"Surefooted_boots",
			k_artifact_winged_sandals,					"Winged Sandals",
		};
		static t_char_ptr_pair const k_bows[] = 
		{
			{ k_artifact_hawkins_bow_of_speed,			"bow of the elf king" },
			{ k_artifact_crossbow,						"crossbow" },
			{ k_artifact_davids_sling,					"davids sling" },
			{ k_artifact_longbow,						"longbow" },
			{ k_artifact_snipers_crossbow,				"sniper's crossbow" },
			{ k_artifact_valders_bow_of_sloth,			"valders bow of sloth" },
			{ k_artifact_tavins_sling,					"war sling" },
		};
		static t_char_ptr_pair const k_capes[] = 
		{
			{ k_artifact_cape_of_protection,			"cape of protection" },
			{ k_artifact_cloak_of_confusion,			"cloak of distraction" },
			{ k_artifact_cowl_of_resistance,			"cowl of resistance" },
			{ k_artifact_mages_robe,					"mages robes" },
			{ k_artifact_mantle_of_spell_turning,		"mantle of spell turning" },
			{ k_artifact_neeners_invulnerable_cloak,	"neeners" },
			{ k_artifact_robe_of_the_guardian,			"robe of the guardian" },
			{ k_artifact_warding_robe,					"warding robe" },
		};
		static t_char_ptr_pair const k_helms[] = 
		{
			{ k_artifact_cap_of_knowledge,				"cap of knowledge" },
			{ k_artifact_circlet_of_wisdom,				"circlet of wisdom" },
			{ k_artifact_crown_of_the_mind,				"crown of the mind" },
			{ k_artifact_helm_of_command,				"helm of command" },
			{ k_artifact_helm_of_power,					"helm of power" },
			{ k_artifact_helm_of_vision,				"helm of vision" },
			{ k_artifact_seamans_hat,					"helm_seamans hat" },
			{ k_artifact_supreme_crown_of_the_magi,		"helm_supreme crown of the magi" },
			{ k_artifact_hideous_mask,					"hideous mask" },
			{ k_artifact_mullichs_helm_of_leadership,	"leadership" },
			{ k_artifact_magic_amplifier,				"magic amplifier" },
			{ k_artifact_mind_shield,					"mind shield" },
		};
		static t_char_ptr_pair const k_items[] = 
		{
			{ k_artifact_equestrians_gloves,	"Equestrian gloves" },
			{ k_artifact_telescope,				"telescope" },
		};
		static t_char_ptr_pair const k_misc[] = 
		{
			{ k_artifact_arms_of_legion,	"arms of legion" },
			{ k_artifact_arrow_of_slaying,	"arrow of slaying" },
			{ k_artifact_arrow_of_stunning,	"arrow of stunning" },
			{ k_artifact_badge_of_courage,	"badge of courage" },
			{ k_artifact_bag_of_gold,		"bag of gold" },
			{ k_artifact_brazier_of_sulfur,	"brazier of sulfur" },
			{ k_artifact_breeze_the_falcon, "breeze_falcon" },
			{ k_artifact_cart_of_lumber,	"cart of lumber" },
			{ k_artifact_cart_of_ore,		"cart of ore" },
			{ k_artifact_crest_of_valor,	"crest of valor" },
			{ k_artifact_crystal_of_memory, "crystal of memory" },
			{ k_artifact_cube_of_crystals,	"crystal_figurine" },
			{ k_artifact_flaming_arrow,		"flaming arrow" },
			{ k_artifact_flask_of_mercury,	"flask of mercury" },
			{ k_artifact_four_leaf_clover,	"four leaf clover" },
			{ k_artifact_gamblers_deck,		"gamblers deck" },
			{ k_artifact_gias_gems,			"gem casket" },
			{ k_artifact_head_of_legion,	"head of legion" },
			{ k_artifact_horseshoe,			"horseshoe" },
			{ k_artifact_legs_of_legion,	"legs of legion" },
			{ k_artifact_marantheas_mug,	"marantheas mug of mirth" },
			{ k_artifact_poison_arrow,		"poison arrow" },
			{ k_artifact_purse_of_gold,		"purse of gold" },
			{ k_artifact_purse_of_pennypinching,	"purse of PennyPinching" },
			{ k_artifact_sack_of_gold,				"sack of gold" },
			{ k_artifact_compass,					"sextant" },
			{ k_artifact_shackles_of_war,			"shackles of war" },
			{ k_artifact_spiders_silk_arrow,		"spiders silk" },
			{ k_artifact_statue_of_legion,			"statue of legion" },
			{ k_artifact_torso_of_legion,			"torso of legion" },
			{ k_artifact_victory_banner,			"victory banner" },
			{ k_artifact_crystal_of_light,			"viewing crystal" },
			{ k_artifact_grail,						"grail" },

		};	
		static t_char_ptr_pair const k_potions[] = 
		{
			{ k_artifact_holy_water,	"holy water" },
			{ k_artifact_potion_of_cold,	"potion of cold" },
			{ k_artifact_potion_of_endurance,	"potion of endurance" },
			{ k_artifact_potion_of_fire_resistance,	"potion of fire resistance" },
			{ k_artifact_potion_of_healing,			"potion of healing" },
			{ k_artifact_potion_of_health,			"potion of health" },
			{ k_artifact_potion_of_luck,			"potion of luck" },
			{ k_artifact_potion_of_mana,			"potion of mana" },
			{ k_artifact_potion_of_mirth,			"potion of mirth" },
			{ k_artifact_potion_of_immortality,	"potion of precognition" },
			{ k_artifact_potion_of_quickness,		"potion of quickness" },
			{ k_artifact_potion_of_resistance,		"potion of resistance" },
			{ k_artifact_potion_of_restoration,		"potion of restoration" },
			{ k_artifact_potion_of_speed,			"potion of speed" },
			{ k_artifact_potion_of_strength,		"potion of strength" },
			{ k_artifact_vial_of_acid,				"vial of acid" },
			{ k_artifact_binding_liquid,			"vial of binding liquid" },
			{ k_artifact_vial_of_blinding_smoke,	"vial of blinding smoke" },
			{ k_artifact_vial_of_choking_gas,		"vial of choking gas" },
			{ k_artifact_cloud_of_despair,			"vial of cloud of despair" },
			{ k_artifact_kreegan_fire,				"vial of kreegan fire" },
			{ k_artifact_vial_of_poison,			"vial of poison" },
		};

		static t_char_ptr_pair const k_rings[] = 
		{
			{ k_artifact_leprechauns_ring,	"leprechauns ring" },
			{ k_artifact_lesser_ring_of_vulnerability,	"lesser ring of vulnerability" },
			{ k_artifact_poison_ring,					"poison ring" },
			{ k_artifact_ring_of_health,				"ring of health" },
			{ k_artifact_ring_of_permanency,			"ring of permanency" },
			{ k_artifact_ring_of_protection,			"ring of protection" },
			{ k_artifact_ring_of_regeneration,			"ring of regeneration" },
			{ k_artifact_ring_of_speed,					"ring of speed" },
			{ k_artifact_ring_of_strength,				"ring of strength" },
			{ k_artifact_ring_of_elementals,			"ring of the elements" },
			{ k_artifact_greater_ring_of_vulnerability,	"ring_greater_negation" },
			{ k_artifact_warlords_ring,					"warlords ring" },
			{ k_artifact_wizards_ring,					"wizards ring" },
		};
		static t_char_ptr_pair const k_shields[] = 
		{
			{ k_artifact_adamantine_shield,		"adamantine shield" },
			{ k_artifact_shield_of_darkness,	"death shield" },
			{ k_artifact_dragon_scale_shield,	"dragonScale shield" },
			{ k_artifact_dwarven_shield,		"dwarven shield" },
			{ k_artifact_shield_of_light,		"life shield" },
			{ k_artifact_lions_shield_of_courage,	"lions shield of courage" },
			{ k_artifact_shield,					"shield" },
			{ k_artifact_shield_of_chaos,			"shield of chaos" },
			{ k_artifact_shield_of_order,			"shield of order" },
			{ k_artifact_steadfast_shield,			"steadfast shield" },
			{ k_artifact_unnatural_shield,			"unnatural shield" },
		};
		static t_char_ptr_pair const k_staves[] = 
		{
			{ k_artifact_caduceus,		"caduceus" },
			{ k_artifact_deadwood_staff,	"deadwood_staff" },
			{ k_artifact_mages_staff,		"mage staff" },
			{ k_artifact_staff_of_death,	"staff of death" },
			{ k_artifact_staff_of_enchantment,	"staff of enchantment" },
			{ k_artifact_staff_of_power,		"staff of power" },
			{ k_artifact_staff_of_summoning,	"staff of summoning" },
			{ k_artifact_staff_of_the_witch_king,	"staff of the WitchKing" },
		};
		static t_char_ptr_pair k_books[] = 
		{
			{ k_artifact_apprentices_handbook,	"apprentices handbook" },
			{ k_artifact_archmages_spellbook,	"archmages codex" },
			{ k_artifact_demonary,				"demonary" },
			{ k_artifact_guildmasters_compendium,	"guildmasters compendium" },
			{ k_artifact_journeymans_notebook,		"journeymens notebook" },
			{ k_artifact_logbook_of_the_master_sailor,	"logbook of the master sailor" },
			{ k_artifact_masters_journal,				"master's spellbook" },
			{ k_artifact_parchment,						"parchment" },
			{ k_artifact_scroll,						"scroll" },
			{ k_artifact_tome_of_chaos,					"tome of chaos" },
			{ k_artifact_tome_of_death,					"tome of death" },
			{ k_artifact_tome_of_life,					"tome of life" },
			{ k_artifact_tome_of_nature,				"tome of nature" },
			{ k_artifact_tome_of_order,					"tome of order" },
		};
		static t_char_ptr_pair k_wands[] = 
		{
			{ k_artifact_wand_of_animate_dead,		"wand of animatedead" },
			{ k_artifact_wand_of_bless,				"wand of bless" },
			{ k_artifact_wand_of_curse,				"wand of curse" },
			{ k_artifact_wand_of_fire,				"wand of fire" },
			{ k_artifact_wand_of_fireball,			"wand of fireball" },
			{ k_artifact_wand_of_haste,				"wand of haste" },
			{ k_artifact_wand_of_healing,			"wand of healing" },
			{ k_artifact_wand_of_ice,				"wand of ice" },
			{ k_artifact_wand_of_illusion,			"wand of illusion" },
			{ k_artifact_wand_of_weakness,			"wand of weakness" },
		};
		static t_char_ptr_pair k_weapons[] = 
		{
			{ k_artifact_axe,					"axe" },
			{ k_artifact_axe_of_legends,		"axe of legends" },
			{ k_artifact_barbarian_throwing_club,	"barbarian throwing club" },
			{ k_artifact_minotaurs_battleax,		"bull rune axe" },
			{ k_artifact_centaurs_spear,			"centaur's spear" },
			{ k_artifact_monks_mace,				"crusaders mace" },
			{ k_artifact_demon_slayer,				"demon_slayer" },
			{ k_artifact_dwarven_hammer,			"dwarven hammer" },
			{ k_artifact_flaming_sword,				"flaming sword" },
			{ k_artifact_giant_slayer,				"giant_slayer" },
			{ k_artifact_greatsword,				"greatsword" },
			{ k_artifact_false_gryphonheart_blade,	"gryphonhearts_false_blade" },
			{ k_artifact_true_gryphonheart_blade,	"gryphonhearts_true_blade" },
			{ k_artifact_halberd_of_speed,			"halberd swiftwatch" },
			{ k_artifact_longsword,					"longsword" },
			{ k_artifact_soul_stealer,				"soul stealer" },
			{ k_artifact_sword_of_swiftness,		"sword of swiftness" },
			{ k_artifact_sword_of_the_gods,			"sword of the gods" },
			{ k_artifact_throwing_spear,			"throwing spear" },
			{ k_artifact_thunder_hammer,			"thunder_hammer" },
			{ k_artifact_tynans_dagger_of_despair,	"tynans_dagger" },
		};

		initialized = true;
		set_model_names( model_names, "artifacts.amulets.", k_amulets, ELEMENTS_OF( k_amulets ));
		set_model_names( model_names, "artifacts.armor.", k_armors, ELEMENTS_OF( k_armors ));
		set_model_names( model_names, "artifacts.boots.", k_boots, ELEMENTS_OF( k_boots ) );
		set_model_names( model_names, "artifacts.bows.", k_bows, ELEMENTS_OF( k_bows ));
		set_model_names( model_names, "artifacts.cloaks.", k_capes, ELEMENTS_OF( k_capes ));
		set_model_names( model_names, "artifacts.helms.", k_helms, ELEMENTS_OF( k_helms ));
		set_model_names( model_names, "artifacts.item.", k_items, ELEMENTS_OF( k_items ));
		set_model_names( model_names, "artifacts.miscellaneous.", k_misc, ELEMENTS_OF( k_misc ));
		set_model_names( model_names, "artifacts.potions.", k_potions, ELEMENTS_OF( k_potions ));
		set_model_names( model_names, "artifacts.rings.", k_rings, ELEMENTS_OF( k_rings ));
		set_model_names( model_names, "artifacts.shields.", k_shields, ELEMENTS_OF( k_shields ));
		set_model_names( model_names, "artifacts.staves.", k_staves, ELEMENTS_OF( k_staves ));
		set_model_names( model_names, "artifacts.tomes-books-manuals.", k_books, ELEMENTS_OF( k_books ));
		set_model_names( model_names, "artifacts.wands.", k_wands, ELEMENTS_OF( k_wands ));
		set_model_names( model_names, "artifacts.weapons.", k_weapons, ELEMENTS_OF( k_weapons ));
	}

	return model_names[type];
}

static t_register_with_type<t_adv_artifact> k_registration( k_adv_object_artifact );
static t_register_with_type<t_adv_spell_artifact> k_scroll_registration( k_adv_object_artifact, k_artifact_scroll );
static t_register_with_type<t_adv_spell_artifact> k_parchment_registration( k_adv_object_artifact, k_artifact_parchment );

extern t_button_cache g_ok_button;

// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
t_adv_artifact::t_adv_artifact(  std::string const& source, 
							     t_qualified_adv_object_type const& object_type )
			  : t_stationary_adventure_object( source )
{
	t_artifact_type				type;
	
	type = t_artifact_type( object_type.major_subtype() );
	m_artifact = get_default_artifact( type );
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// construct from a default artifact type
// -------------------------------------------------------
t_adv_artifact::t_adv_artifact( t_artifact_type type )
			  : t_stationary_adventure_object( get_artifact_model_name( type ) )
{
	t_adv_object_model const&	model = get_model();
	
	m_artifact = get_default_artifact( type );
}


// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
void t_adv_artifact::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                               t_direction direction, t_adventure_frame* frame )
{
	destroy(); // we should not be deleted by this, because the caller has a reference.
	if (!army->get_owner()->is_computer())
	{
		army->add( m_artifact );

		std::string text = m_artifact.get_pickup_text();
		std::string name = m_artifact.get_name();
		t_adventure_map*		 map = get_map();
		t_adventure_map_window*  map_window = frame->get_map_window();
		t_level_map_point_2d     location = get_position();
		t_screen_point           screen_point = get_screen_point( *map, *this, location )
												- map_window->get_view_pos();
		t_artifact_type          type = m_artifact.get_icon();
		t_bitmap_layer_ptr       icon = get_icon( type );

		//t_bitmap_layer_cache_window_ptr icon_window;
		t_counted_ptr<t_basic_dialog>	dialog = new t_basic_dialog( frame );

		dialog->add_ok_button();
		//icon_window = new t_bitmap_layer_cache_window( icon, t_screen_point(0,0), dialog, false );
		//icon_window->set_help_balloon_text( m_artifact.get_name() );
		//icon_window->set_right_click_text( m_artifact.get_help_text() );
		dialog->add_artifact( m_artifact, 1, true );
		dialog->set_text( text );
		//dialog->add_display_window( icon_window, name );
		dialog->set_title( get_name() );
		dialog->open( screen_point, true, k_align_bottom );
		t_sound_cache music = get_music_playing();
		stop_music();
		get_dialog_sound( k_dialog_sound_treasure )->play( get_sound_volume() );
		dialog->run_modal();
		play_music( music );
	} 
	else 
		ai_give_artifact_to_army( *army, m_artifact );
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// mark artifact as used for random purposes
// -------------------------------------------------------
bool t_adv_artifact::preplacement( t_adventure_map& map, int pass )
{
	map.use_artifact( m_artifact.get_icon() );
	return false;
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
std::string	t_adv_artifact::get_name() const
{
	return m_artifact.get_name();
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
void t_adv_artifact::right_click( t_mouse_event const& event,
                                  t_adventure_frame* adventure_frame )
{
	std::string help_text;
    help_text = format_string("%s: %s", m_artifact.get_name().c_str(), m_artifact.get_help_text().c_str());

	if (help_text.empty())
		return;

	show_popup_text( help_text, event.screen_point );
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
bool t_adv_artifact::write( std::streambuf& stream ) const
{
	return m_artifact.write( stream );
}

// -------------------------------------------------------
// artifact as it appears on the adventure map
// -------------------------------------------------------
bool t_adv_artifact::read( std::streambuf&						stream, 
					       t_qualified_adv_object_type const&	type,
					       int									version )
{
	return m_artifact.read( stream );
}

// -------------------------------------------------------
// -------------------------------------------------------
float t_adv_artifact::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	return std::max(ai_value_of_artifact_simple( army, m_artifact.get_icon() ), k_ai_minimum_artifact_value_level);
}

// -------------------------------------------------------
// t_adv_spell_artifact
// -------------------------------------------------------
t_adv_spell_artifact::t_adv_spell_artifact(  std::string const& source, t_qualified_adv_object_type const& type )
	: t_adv_artifact( source, type )
{
	if ( type.major_subtype() == k_artifact_scroll )
	{
		m_artifact = get_scroll_artifact( k_spell_bless );
	}
	else 
	{
		assert( type.major_subtype() == k_artifact_parchment );
		m_artifact = get_parchment( k_spell_bless );
	}
}

t_adv_spell_artifact::t_adv_spell_artifact( t_artifact_type type, t_spell spell )
	: t_adv_artifact( type )
{
	if ( type == k_artifact_scroll )
	{
		m_artifact = get_scroll_artifact( spell );
	}
	else 
	{
		assert( type == k_artifact_parchment );
		m_artifact = get_parchment( spell );
	}
}

// -------------------------------------------------------
// Spell-based artifacts
// -------------------------------------------------------
bool t_adv_spell_artifact::read_from_map( std::streambuf & stream,
										t_progress_handler* )
{
	t_uint16 version = get< t_uint16 >( stream );

	if ( version > k_spell_artifact_map_version )
		return false;

	if ( version == 0 )
		return true;

	t_spell spell = t_spell( get< int >( stream ) );

	if ( get_type().major_subtype() == k_artifact_scroll )
	{
		m_artifact = get_scroll_artifact( spell );
	}
	else 
	{
		assert( get_type().major_subtype() == k_artifact_parchment );
		m_artifact = get_parchment( spell );
	}

	return true;
}


static t_object_registration<t_random_artifact> 
	k_random_registration( k_adv_object_random_artifact );

// -------------------------------------------------------
// random artifact as it appears on the adventure map
// -------------------------------------------------------
t_random_artifact::t_random_artifact( std::string const& model_name )
                 : t_stationary_adventure_object( model_name )
{
}

// -------------------------------------------------------
// random artifact as it appears on the adventure map
// -------------------------------------------------------
void t_random_artifact::place( t_adventure_map &		map,
							   t_adv_map_point const& point )
{
	t_artifact_type				  type;
	t_artifact_level			  level;
	t_counted_ptr<t_adv_artifact> artifact;

	level = t_artifact_level( get_major_subtype() );
	type = map.get_random_artifact( level );
	artifact = new t_adv_artifact( type );
	artifact->place( map, point );
}

static t_object_registration<t_random_tome> 
	k_random_tome_registration( k_adv_object_random_tome );
// -------------------------------------------------------
// random tome
// -------------------------------------------------------
t_random_tome::t_random_tome( std::string const& source )
             : t_stationary_adventure_object( source )
{
}

// -------------------------------------------------------
// random tome
// -------------------------------------------------------
void t_random_tome::place( t_adventure_map &		map,
						   t_adv_map_point const&	point )
{
	static t_artifact_type const k_tomes[] = 
	{ k_artifact_tome_of_life,  k_artifact_tome_of_order,
	  k_artifact_tome_of_death, k_artifact_tome_of_chaos, k_artifact_tome_of_nature };

	t_artifact_type				  type;
	t_counted_ptr<t_adv_artifact> artifact;

	type = map.get_random_artifact( k_tomes, ELEMENTS_OF( k_tomes ));
	artifact = new t_adv_artifact( type );
	artifact->place( map, point );
};

static t_object_registration<t_random_staff> 
	k_random_staff_registration( k_adv_object_random_staff );

// -------------------------------------------------------
// random staff
// -------------------------------------------------------
t_random_staff::t_random_staff( std::string const& source )
              : t_stationary_adventure_object( source )
{
}

// -------------------------------------------------------
// random staff
// -------------------------------------------------------
void t_random_staff::place( t_adventure_map &		map,
						    t_adv_map_point const&	point )
{
	static t_artifact_type const k_staves[] = 
	{ k_artifact_caduceus,  k_artifact_staff_of_enchantment,
	  k_artifact_staff_of_death, k_artifact_staff_of_the_witch_king, 
	  k_artifact_staff_of_summoning };

	t_artifact_type				  type;
	t_counted_ptr<t_adv_artifact> artifact;

	type = map.get_random_artifact( k_staves, ELEMENTS_OF( k_staves ));
	artifact = new t_adv_artifact( type );
	artifact->place( map, point );
};


static t_object_registration<t_random_potion> 
	k_random_potion_registration( k_adv_object_random_potion );

// -------------------------------------------------------
// random potion
// -------------------------------------------------------
t_random_potion::t_random_potion( std::string const& source )
              : t_stationary_adventure_object( source )
{
}

// -------------------------------------------------------
// random potion
// -------------------------------------------------------
void t_random_potion::place( t_adventure_map &		map,
						    t_adv_map_point const&	point )
{
	t_artifact_type				  type;
	t_counted_ptr<t_adv_artifact> artifact;

	type = map.get_random_potion( );
	artifact = new t_adv_artifact( type );
	artifact->place( map, point );
};

